# encoding utf-8

import requests
from typing import Optional, Dict
from config.settings import settings
from loguru import logger


class OptionsService:
    """期权数据服务类"""
    
    def __init__(self):
        self.base_url = settings.data_query_host
    
    def get_options_skew_data(self, underlying_symbol: str, target_date: str) -> Optional[Dict]:
        """
        查询期权波动率偏斜(skew)数据
        
        Args:
            underlying_symbol (str): 标的合约代码，例如：'SSE.000852'
            target_date (str): 目标日期，格式为 YYYY-MM-DD，例如：'2025-08-10'
            
        Returns:
            Dict: 期权skew数据，以到期日为key的字典，每个到期日包含skew数据点数组
            None: 如果获取失败
        """
        try:
            # 调用API获取数据
            api_url = f"{self.base_url}/data_query/options_skew"
            params = {
                'underlying_symbol': underlying_symbol,
                'target_date': target_date
            }
            data = self._fetch_from_api(api_url, params)
            
            if data and data.get('code') == 200:
                return data.get('data', {})
            else:
                logger.error(f"API返回错误: {data.get('message', 'Unknown error') if data else 'No response'}")
                return None
                
        except Exception as e:
            logger.error(f"获取期权skew数据失败: {e}")
            return None
    
    def get_options_atm_historical_iv(self, underlying_symbol: str, start_date: str, end_date: str, option_class: str) -> Optional[Dict]:
        """
        查询期权平值历史隐含波动率
        
        Args:
            underlying_symbol (str): 标的合约代码
            start_date (str): 开始日期 (YYYY-MM-DD)
            end_date (str): 结束日期 (YYYY-MM-DD)
            option_class (str): 期权类型 ('CALL' 或 'PUT')
            
        Returns:
            Dict: 历史IV数据
            None: 如果获取失败
        """
        try:
            api_url = f"{self.base_url}/data_query/options_atm_historical_iv"
            params = {
                'underlying_symbol': underlying_symbol,
                'start_date': start_date,
                'end_date': end_date,
                'option_class': option_class
            }
            data = self._fetch_from_api(api_url, params)
            
            if data and data.get('code') == 200:
                return data.get('data', {})
            else:
                logger.error(f"API返回错误: {data.get('message', 'Unknown error') if data else 'No response'}")
                return None
                
        except Exception as e:
            logger.error(f"获取期权历史IV数据失败: {e}")
            return None

    def get_iv_history(self, underlying_symbol: str, start_date: str, end_date: str, 
                      moneyness: Optional[int] = None, is_nearby_month: Optional[int] = None) -> Optional[list]:
        """
        查询期权隐含波动率历史数据
        
        Args:
            underlying_symbol (str): 标的合约代码，例如：'SSE.000852'
            start_date (str): 开始日期，格式为 YYYY-MM-DD，例如：2025-01-01
            end_date (str): 结束日期，格式为 YYYY-MM-DD，例如：2025-01-31
            moneyness (Optional[int]): 价格相对性，默认None查询全部
                -1: 虚值期权
                0: 平值期权
                1: 实值期权
            is_nearby_month (Optional[int]): 是否近月合约，默认None查询全部
                0: 非近月合约
                1: 近月合约
                None: 查询全部合约
                
        Returns:
            list: IV历史数据列表
            None: 如果获取失败
        """
        try:
            api_url = f"{self.base_url}/data_query/iv_history"
            params = {
                'underlying_symbol': underlying_symbol,
                'start_date': start_date,
                'end_date': end_date
            }
            
            # 添加可选参数
            if moneyness is not None:
                params['moneyness'] = moneyness
            if is_nearby_month is not None:
                params['is_nearby_month'] = is_nearby_month
                
            data = self._fetch_from_api(api_url, params)
            
            if data and data.get('code') == 200:
                return data.get('data', [])
            else:
                logger.error(f"API返回错误: {data.get('message', 'Unknown error') if data else 'No response'}")
                return None
                
        except Exception as e:
            logger.error(f"获取IV历史数据失败: {e}")
            return None

    def get_options_cone_data(self, underlying_symbol: str, target_date: str) -> Optional[Dict]:
        """
        查询期权波动率锥(cone)数据
        
        Args:
            underlying_symbol (str): 标的合约代码，例如：'SSE.000852'
            target_date (str): 目标日期，格式为 YYYY-MM-DD，例如：'2025-08-10'
            
        Returns:
            Dict: 期权锥数据，包含call和put两个key，每个包含以到期日为key的字典
            None: 如果获取失败
        """
        try:
            api_url = f"{self.base_url}/data_query/options_cone"
            params = {
                'underlying_symbol': underlying_symbol,
                'target_date': target_date
            }
            data = self._fetch_from_api(api_url, params)
            
            if data and data.get('code') == 200:
                return data.get('data', {})
            else:
                logger.error(f"API返回错误: {data.get('message', 'Unknown error') if data else 'No response'}")
                return None
                
        except Exception as e:
            logger.error(f"获取期权锥数据失败: {e}")
            return None

    def get_options_iv_surface_data(self, underlying_symbol: str, date: str, option_class: str) -> Optional[list]:
        """
        查询期权隐含波动率曲面数据
        
        Args:
            underlying_symbol (str): 标的合约代码，例如：'SSE.000852'
            date (str): 查询日期，格式为 YYYY-MM-DD，例如：'2025-08-10'
            option_class (str): 期权类型，'CALL' 或 'PUT'
            
        Returns:
            list: 期权隐含波动率曲面数据，包含expire_date, strike_price, iv等字段
            None: 如果获取失败
        """
        try:
            # 调用API获取数据
            api_url = f"{self.base_url}/data_query/options_iv_surface"
            params = {
                'underlying_symbol': underlying_symbol,
                'date': date,
                'option_class': option_class
            }
            data = self._fetch_from_api(api_url, params)
            
            if data and data.get('code') == 200:
                return data.get('data', [])
            else:
                logger.error(f"API返回错误: {data.get('message', 'Unknown error') if data else 'No response'}")
                return None
                
        except Exception as e:
            logger.error(f"获取期权隐含波动率曲面数据失败: {e}")
            return None

    def _fetch_from_api(self, url: str, params: Dict) -> Optional[Dict]:
        """通用API获取函数"""
        try:
            logger.info(f"发起API请求: {url}")
            logger.info(f"请求参数: {params}")
            
            response = requests.get(
                url,
                params=params,
                timeout=settings.request_timeout_seconds,
            )
            
            logger.info(f"响应状态码: {response.status_code}")
            logger.info(f"响应头: {dict(response.headers)}")
            logger.info(f"响应内容长度: {len(response.content)}")
            
            # 打印原始响应内容用于调试
            if response.content:
                logger.info(f"响应内容前500字符: {response.text[:500]}")
            else:
                logger.warning("响应内容为空")
            
            response.raise_for_status()
            
            if not response.content.strip():
                logger.error("服务器返回空响应")
                return None
                
            return response.json()
        except requests.exceptions.RequestException as e:
            logger.error(f"API请求失败: {e}")
            logger.error(f"请求URL: {url}")
            logger.error(f"请求参数: {params}")
            raise
        except ValueError as e:
            logger.error(f"JSON解析失败: {e}")
            logger.error(f"响应内容: {response.text if 'response' in locals() else 'N/A'}")
            raise
        except Exception as e:
            logger.error(f"其他错误: {e}")
            raise
